﻿using System;
using System.Collections.Generic;

namespace RSSFeedReader.Data.Models
{
    /// <summary>
    /// Used to hold data relating to the channel feed.
    /// </summary>
    [Serializable]
    public class Channel : FeedBase
    {
        #region Fields

        List<Post> _posts;
        ChannelType _channelType;
        List<Channel> _children = new List<Channel>();
        Guid _channelID;
        Guid _parentID;

        #endregion

        #region Constructor

        /// <summary>
        /// Initialize a new instance of the <see cref="RSSFeedReader.Data.Models.Channel"/> class.
        /// </summary>
        public Channel()
        {
            _channelType = Models.ChannelType.None;
        }

        /// <summary>
        /// Initialize a new instance of the <see cref="RSSFeedReader.Data.Models.Channel"/> class.
        /// </summary>
        /// <param name="channelID">The ID of the channel.</param>
        /// <param name="title">The title of the channel.</param>
        /// <param name="description">The description of the channel.</param>
        /// <param name="link">The link to the channel.</param>
        /// <param name="imageUrl">The image associated with the channel.</param>
        /// <param name="url">The url to the channel.</param>
        public Channel(Guid channelID, string title, string description, string link, string imageUrl, string url)
            : base(title, description, link)
        {
            _channelID = channelID;
            ImageUrl = imageUrl;
            Url = url;
            _channelType = Models.ChannelType.None;
        }

        /// <summary>
        /// Initialize a new instance of the <see cref="RSSFeedReader.Data.Models.Channel"/> class.
        /// </summary>
        /// <param name="channelID">The ID of the channel.</param>
        /// <param name="parent">The parent <see cref="RSSFeedReader.Data.Models.Channel"/>
        /// of this <see cref="RSSFeedReader.Data.Models.Channel"/> instance.</param>
        /// <param name="title">The title of the channel.</param>
        /// <param name="description">The description of the channel.</param>
        /// <param name="link">The link to the channel.</param>
        /// <param name="imageUrl">The image associated with the channel.</param>
        /// <param name="url">The url to the channel.</param>
        public Channel(Guid channelID, Channel parent, string title, string description, string link, string imageUrl, string url)
            : base(title, description, link)
        {
            if (parent == null)
                throw new ArgumentNullException("parent");

            _channelID = channelID;
            ImageUrl = imageUrl;
            Url = url;
            _channelType = Models.ChannelType.None;
            _parentID = parent.ChannelID;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets the ID of the channel.
        /// </summary>
        public Guid ChannelID
        {
            get
            {
                if (_channelID == Guid.Empty)
                    _channelID = Guid.NewGuid();

                return _channelID;
            }
            set { _channelID = value; }
        }

        /// <summary>
        /// Gets or sets Url of the feed.
        /// </summary>
        public string Url { get; set; }

        /// <summary>
        /// The Image associated with the feed.
        /// </summary>
        public string ImageUrl { get; set; }

        /// <summary>
        /// Gets or sets the List of type <see cref="RSSFeedReader.Data.Models.Post"/> belonging to this instance.
        /// </summary>
        public List<Post> Posts
        {
            get
            {
                if (_posts == null)
                    _posts = new List<Post>();

                return _posts;
            }
            set
            {
                _posts = value;
            }
        }

        /// <summary>
        /// Gets or sets the <see cref="RSSFeedReader.Data.Models.ChannelType"/> of this instance.
        /// </summary>
        public ChannelType ChannelType
        {
            get
            {
                if (_channelType == Models.ChannelType.None)
                    _channelType = Models.ChannelType.Feed;

                return _channelType;
            }
            set { _channelType = value; }
        }

        /// <summary>
        /// Gets the IList of type <see cref="RSSFeedReader.Data.Models.Channel"/>
        /// that are the children of the current <see cref="RSSFeedReader.Data.Models.Channel"/>.
        /// </summary>
        public List<Channel> Children
        {
            get { return _children; }
        }

        /// <summary>
        /// Gets or sets the parent <see cref="RSSFeedReader.Data.Models.Channel"/>
        /// of this <see cref="RSSFeedReader.Data.Models.Channel"/> instance.
        /// </summary>
        public Guid ParentID
        {
            get { return _parentID; }
            set { _parentID = value; }
        }

        #endregion

        #region Base Class Overrides

        /// <summary>
        /// Determines whether this instance of <see cref="RSSFeedReader.Data.Models.Channel"/> and a specified object,
        /// which must also be a <see cref="RSSFeedReader.Data.Models.Channel"/> object, have the same value.
        /// </summary>
        /// <param name="obj">An System.Object</param>
        /// <returns>true if obj is a <see cref="RSSFeedReader.Data.Models.Channel"/> and its value is the same as this instance;
        /// otherwise, false.</returns>
        public override bool Equals(object obj)
        {
            Channel other = obj as Channel;

            if (obj == null)
                return false;

            return ChannelID == other.ChannelID;
        }

        /// <summary>
        /// Returns the hashcode for this string.
        /// </summary>
        /// <returns>A 32-bit signed integer hash code.</returns>
        public override int GetHashCode()
        {
            return ChannelID.GetHashCode();
        }

        #endregion
    }
}
